<!DOCTYPE html>
<html lang="zh-CN">

<head>
  <meta charset="UTF-8" />
  <meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=no" />
  <meta name="apple-mobile-web-app-capable" content="yes" />
  <meta name="apple-mobile-web-app-status-bar-style" content="black-translucent" />
  <script src="./js/jquery.js"></script>
  <title>人脸识别</title>
  <style>
    * {
      margin: 0;
      padding: 0;
      box-sizing: border-box;
      -webkit-tap-highlight-color: transparent;
      font-family: "PingFang SC", "Helvetica Neue", Arial, sans-serif;
    }

    body {
      background: #f0f2f5;
      color: #333;
      line-height: 1.6;
      padding: 0;
      display: flex;
      justify-content: center;
      align-items: center;
      min-height: 100vh;
      -webkit-font-smoothing: antialiased;
      -moz-osx-font-smoothing: grayscale;
    }

    .container {
      width: 100%;
      max-width: 480px;
      margin: 20px auto;
      padding: 20px;
    }

    .card {
      border-radius: 16px;
      overflow: hidden;
      transition: all 0.3s ease;
    }

    .instruction {
      font-size: 16px;
      color: #333;
      text-align: center;
      margin: 20px 0;
      padding: 12px;
      border-radius: 8px;
      transition: all 0.3s ease;
      font-weight: 500;
    }

    .camera-container {
      position: relative;
      width: 100%;
      max-width: 280px;
      aspect-ratio: 1 / 1;
      margin: 0 auto 25px;
      border-radius: 50%;
      overflow: hidden;
      box-shadow: 0 6px 18px rgba(0, 0, 0, 0.15);
      background: transparent;
    }

    #video {
      width: 100%;
      height: 100%;
      display: block;
      transform: scaleX(-1) scale(1.2);
      object-fit: contain;
    }

    .face-overlay {
      position: absolute;
      top: 50%;
      left: 50%;
      transform: translate(-50%, -50%);
      width: 100%;
      height: 100%;
      border: 3px solid rgba(255, 255, 255, 0.7);
      border-radius: 50%;
      z-index: 10;
      box-shadow: 0 0 0 4000px rgba(0, 0, 0, 0.4);
      pointer-events: none;
    }

    .scanning-effect {
      position: absolute;
      top: 50%;
      left: 50%;
      transform: translate(-50%, -50%);
      width: 100%;
      height: 100%;
      border-radius: 50%;
      overflow: hidden;
      pointer-events: none;
    }

    .scanning-line {
      position: absolute;
      height: 3px;
      width: 100%;
      background: linear-gradient(to right, transparent, #1e88e5, transparent);
      top: 0;
      animation: scan 2s linear infinite;
      border-radius: 3px;
    }

    .pulse-ring {
      position: absolute;
      top: 50%;
      left: 50%;
      transform: translate(-50%, -50%);
      width: 105%;
      height: 105%;
      border: 2px solid rgba(30, 136, 229, 0.6);
      border-radius: 50%;
      animation: pulse 3s infinite;
      pointer-events: none;
    }

    @keyframes scan {
      0% {
        top: 0;
      }

      100% {
        top: 100%;
      }
    }

    @keyframes pulse {
      0% {
        width: 105%;
        height: 105%;
        opacity: 1;
      }

      50% {
        width: 115%;
        height: 115%;
        opacity: 0.7;
      }

      100% {
        width: 105%;
        height: 105%;
        opacity: 1;
      }
    }

    .controls {
      display: flex;
      flex-direction: column;
      gap: 16px;
      margin-top: 25px;
    }

    .btn {
      padding: 16px 24px;
      border: none;
      border-radius: 100px;
      font-size: 16px;
      font-weight: 500;
      cursor: pointer;
      transition: all 0.2s;
      display: flex;
      align-items: center;
      justify-content: center;
      gap: 10px;
      touch-action: manipulation;
    }

    .btn:active {
      transform: scale(0.98);
    }

    .btn-primary {
      background: #004b9a;
      color: white;
      box-shadow: 0 4px 10px rgba(30, 136, 229, 0.4);
    }

    .btn-primary:active {
      background: #003a7a;
      box-shadow: 0 2px 6px rgba(30, 136, 229, 0.4);
    }

    .footer {
      margin-top: 25px;
    }

    .footer-tips {
      font-size: 14px;
      color: #666;
      text-align: center;
      margin-bottom: 15px;
    }

    .row-container {
      display: flex;
      justify-content: space-around;
      gap: 10px;
    }

    .row-item {
      display: flex;
      flex-direction: column;
      align-items: center;
      text-align: center;
      flex: 1;
    }

    .row-area-img-box {
      width: 44px;
      height: 44px;
      display: flex;
      justify-content: center;
      align-items: center;
      border-radius: 50%;
      background-color: #f0f2f5;
      overflow: hidden;
      margin-bottom: 8px;
    }

    .row-area-img {
      width: 24px;
      height: 24px;
      object-fit: contain;
    }

    .row-area-tip {
      font-size: 12px;
      color: #333;
    }

    .status-message {
      text-align: center;
      margin-top: 15px;
      font-size: 14px;
      color: #666;
      min-height: 20px;
    }

    /* 响应式设计 */
    @media (max-width: 480px) {
      .container {
        padding: 15px;
      }

      .card {
        padding: 15px;
        border-radius: 12px;
      }

      .instruction {
        font-size: 15px;
        margin: 15px 0;
      }

      .camera-container {
        max-width: 220px;
      }

      .btn {
        padding: 14px 20px;
        font-size: 15px;
      }

      .row-area-img-box {
        width: 40px;
        height: 40px;
      }

      .row-area-img {
        width: 22px;
        height: 22px;
      }

      .row-area-tip {
        font-size: 11px;
      }
    }

    @media (max-width: 360px) {
      .container {
        padding: 10px;
      }

      .card {
        padding: 12px;
      }

      .instruction {
        font-size: 14px;
        padding: 10px;
      }

      .camera-container {
        max-width: 200px;
      }

      .btn {
        padding: 12px 18px;
        font-size: 14px;
      }

      .row-container {
        gap: 5px;
      }

      .row-area-img-box {
        width: 36px;
        height: 36px;
      }

      .row-area-img {
        width: 20px;
        height: 20px;
      }

      .row-area-tip {
        font-size: 10px;
      }
    }

    /* 横屏适配 */
    @media (max-height: 500px) and (orientation: landscape) {
      .container {
        padding: 10px;
      }

      .card {
        display: flex;
        flex-direction: row;
        align-items: center;
        gap: 15px;
      }

      .camera-container {
        margin-bottom: 0;
        flex-shrink: 0;
        max-width: 150px;
      }

      .card-body {
        flex: 1;
      }

      .instruction {
        margin-top: 0;
      }

      .footer {
        margin-top: 15px;
      }
    }

    /* 深色模式支持 */
    @media (prefers-color-scheme: dark) {
      body {
        background: #121212;
        color: #e0e0e0;
      }

      .card {
        background: #1e1e1e;
      }

      .instruction {
        background-color: #2d2d2d;
        color: #e0e0e0;
      }

      .row-area-img-box {
        background-color: #2d2d2d;
      }

      .row-area-tip {
        color: #e0e0e0;
      }

      .footer-tips {
        color: #aaa;
      }
    }
  </style>
</head>

<body>
  <div class="container">
    <div class="card">
      <div class="card-body">
        <div class="instruction">
          请把人脸放在圆圈内拍摄脸部，开始人脸录入
        </div>

        <div class="camera-container">
          <video id="video" autoplay playsinline muted></video>
          <div class="face-overlay">
            <div class="scanning-effect">
              <div class="scanning-line"></div>
            </div>
          </div>
          <div class="pulse-ring"></div>
        </div>

        <div class="controls">
          <button class="btn btn-primary" id="captureBtn"> </button>
        </div>

        <div class="status-message" id="statusMessage"></div>

        <div class="footer">
          <div class="footer-required">
            <div class="row-container">
              <div class="row-item">
                <div class="row-area-img-box">
                  <img class="row-area-img" src="../../static/face/img3.png" alt="正对手机">
                </div>
                <div class="row-area-tip">正对手机</div>
              </div>
              <div class="row-item">
                <div class="row-area-img-box">
                  <img class="row-area-img" src="../../static/face/img1.png" alt="光线充足">
                </div>
                <div class="row-area-tip">光线充足</div>
              </div>
              <div class="row-item">
                <div class="row-area-img-box">
                  <img class="row-area-img" src="../../static/face/img2.png" alt="脸无遮挡">
                </div>
                <div class="row-area-tip">脸无遮挡</div>
              </div>
            </div>
          </div>
        </div>
      </div>
    </div>

  </div>

  <canvas id="canvas" style="display: none;"></canvas>


  <script type="module">
    let isfirstrlsbstatus = null;
    let isCountingDown = false;
    const video = document.getElementById('video');
    const canvas = document.getElementById('canvas');
    const ctx = canvas.getContext('2d');
    const statusMessage = document.getElementById('statusMessage');
    const captureBtn = document.getElementById('captureBtn');
    let userinformation = JSON.parse(localStorage.getItem('user')).user
    let base64Image = null
    // 设置Canvas尺寸与视频流相同
    function setupCanvas () {
      if (video.videoWidth && video.videoHeight) {
        canvas.width = video.videoWidth;
        canvas.height = video.videoHeight;
        video.style.width = '100%';
        video.style.height = '100%';
        video.style.objectFit = 'cover';
      }
    }

    // 开启摄像头
    async function startCamera () {
      try {
        // 停止现有流
        if (video.srcObject) {
          video.srcObject.getTracks().forEach(track => track.stop());
        }

        // 禁用动画，减少 GPU 占用
        disableAnimations();

        const stream = await navigator.mediaDevices.getUserMedia({
          video: {
            facingMode: 'user',
            width: { ideal: 640 },
            height: { ideal: 480 }
          },
          audio: false
        });
        video.srcObject = stream;

        video.onloadedmetadata = () => {
          // 延迟设置 canvas，避免 iOS PWA 闪断
          setTimeout(() => {
            setupCanvas();
            // 恢复动画
            enableAnimations();
            video.play();
          }, 500);
        };

      } catch (err) {
        statusMessage.textContent = '无法访问摄像头: ' + err.message;
        console.error('摄像头错误:', err);
      }
    }

    // 禁用动画
    function disableAnimations() {
      const scanningLine = document.querySelector('.scanning-line');
      const pulseRing = document.querySelector('.pulse-ring');
      if (scanningLine) scanningLine.style.animation = 'none';
      if (pulseRing) pulseRing.style.animation = 'none';
    }


    // 启用动画
    function enableAnimations() {
      const scanningLine = document.querySelector('.scanning-line');
      const pulseRing = document.querySelector('.pulse-ring');
      if (scanningLine) scanningLine.style.animation = 'scan 2s linear infinite';
      if (pulseRing) pulseRing.style.animation = 'pulse 3s infinite';
    }

    function dataURLtoBlob (dataurl) {
      const arr = dataurl.split(',');
      const mime = arr[0].match(/:(.*?);/)[1]; // 获取 MIME 类型
      const bstr = atob(arr[1]); // 解码 Base64
      let n = bstr.length;
      const u8arr = new Uint8Array(n);

      while (n--) {
        u8arr[n] = bstr.charCodeAt(n);
      }

      return new Blob([u8arr], { type: mime });
    }

    // 抓拍并上传
    function captureAndUpload () {
      if (!video.videoWidth || !video.videoHeight) {
        statusMessage.textContent = '摄像头未准备好，请稍后再试';
        return;
      }

      captureBtn.disabled = true;

      // 绘制镜像图像
      ctx.save();
      ctx.translate(canvas.width, 0);
      ctx.scale(-1, 1);
      ctx.drawImage(video, 0, 0, canvas.width, canvas.height);
      ctx.restore();

      // 获取Base64图像
      base64Image = canvas.toDataURL('image/jpeg', 0.8);
      simulateUpload(base64Image)
    }

    // 模拟上传过程
    function simulateUpload (tempUrl) {
      setTimeout(() => {
        window.parent.postMessage({
          type: 'ModifygetFaceregistration',
          params: tempUrl
        }, '*');
      }, 100);
      resetCameraPreview();
    }


    // 新增：重置相机预览
    function resetCameraPreview () {
      base64Image = null
      const cameraContainer = document.querySelector('.camera-container');
      const video = document.getElementById('video');

      // 添加重置动画类
      cameraContainer.classList.add('resetting');
      video.classList.add('resetting');

      // 重置尺寸和位置
      cameraContainer.style.transform = 'scale(1)';
      video.style.transform = 'scaleX(-1) scale(1.2)'; // 保持镜像

      // 重新设置canvas尺寸
      setupCanvas();

      // 重启扫描动画
      restartScanningAnimation();
      // 移除动画类
      setTimeout(() => {
        cameraContainer.classList.remove('resetting');
        video.classList.remove('resetting');
      }, 500);
    }

    // 新增：重启扫描动画
    function restartScanningAnimation () {
      const scanningLine = document.querySelector('.scanning-line');
      const pulseRing = document.querySelector('.pulse-ring');

      // 移除并重新添加动画类以重启动画
      scanningLine.classList.remove('reset-animation');
      pulseRing.classList.remove('reset-animation');

      // 强制重绘
      void scanningLine.offsetWidth;
      void pulseRing.offsetWidth;

      // 重新添加动画
      scanningLine.style.animation = 'scan 2s linear infinite';
      pulseRing.style.animation = 'pulse 3s infinite';
    }


    captureBtn.addEventListener('click', handleCaptureClick);

    // 处理按钮点击事件
    function handleCaptureClick () {
      // 如果已经在倒计时，直接返回，防止重复触发
      if (isCountingDown) return;

      // 设置标志变量为 true，表示开始倒计时
      isCountingDown = true;

      // 禁用按钮
      captureBtn.disabled = true;

      // 设置倒计时时间（3秒）
      let countdown = 1;

      // 更新按钮文本为倒计时
      captureBtn.textContent = `正在抓拍中 ${countdown} 秒`;

      // 定义倒计时定时器
      const countdownInterval = setInterval(() => {
        countdown--;
        if (countdown > 0) {
          // 更新按钮文本
          captureBtn.textContent = `正在抓拍中 ${countdown} 秒`;
        } else {
          // 清除定时器
          clearInterval(countdownInterval);

          // 恢复按钮状态并执行抓拍
          captureBtn.textContent = isfirstrlsbstatus == 1 ? '上传人脸' : '上传人脸注册';
          captureBtn.disabled = false;

          // 倒计时结束，重置标志变量
          isCountingDown = false;

          // 执行抓拍操作
          captureAndUpload();
        }
      }, 1000); // 每秒更新一次
    }

    // 添加触摸事件支持
    captureBtn.addEventListener('touchstart', function (e) {
      e.preventDefault();
      this.style.opacity = '0.8';
    });

    captureBtn.addEventListener('touchend', function (e) {
      e.preventDefault();
      this.style.opacity = '1';
      handleCaptureClick();
    });

    // 页面加载后自动打开摄像头
    window.addEventListener('load', () => {
      getKaoqinisfirstrlsb()
    });


    async function getKaoqinisfirstrlsb () {
      $.ajax({
        url: 'https://cloud.mfarmers.com/dist/interface/public/index.php/index/Kaoqin/is_first_rlsb',
        type: 'POST',
        contentType: 'application/json',
        data: JSON.stringify({
          phone: userinformation.phone,
          token: userinformation.token,
        }),
        success: function (res) {
          if (res.status == 1) {
            isfirstrlsbstatus = res.status
          } else if (res.status == 0) {
            isfirstrlsbstatus = res.status
          }
          updateUIBasedOnStatus(res.status);
          startCamera();
        },
        error: function (xhr, status, error) {
        }
      });


    }

    // 处理页面可见性变化
    document.addEventListener('visibilitychange', function () {
      if (document.hidden) {
        if (video.srcObject) {
          video.srcObject.getTracks().forEach(track => track.stop());
        }
      } else {
        startCamera();
      }
    });

    // 处理设备方向变化
    window.addEventListener('resize', setupCanvas);
    window.addEventListener('orientationchange', function () {
      setTimeout(setupCanvas, 300);
    });
    // 更新界面的函数
    function updateUIBasedOnStatus (status) {
      const captureBtn = document.getElementById('captureBtn');
      const instruction = document.querySelector('.instruction');

      if (status == 1) {
        captureBtn.textContent = '上传人脸';
        instruction.textContent = '请把人脸放在圆圈内拍摄脸部，开始上传人脸';
        captureBtn.style.backgroundColor = '#2db66d';
      } else if (status == 0) {
        captureBtn.textContent = '上传人脸注册';
        instruction.textContent = '请先上传人脸照片进行注册';
        captureBtn.style.backgroundColor = '#2db66d';
      }
    }

  </script>
</body>

</html>